package mail_operations;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Dictionary;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import javax.swing.text.html.HTMLDocument;

import data.ConfigInfo;
import data.FilePath;

import GUIMain.GUIFocusManager;

/**
 * Allows the user to set options regarding the addressee, subject text etc
 * @author lax116
 *
 */
public class MailerGUI {
	private static JDialog dialog;
	private static JLabel subjectLabel;
	private static JTextField subjectField;
	private static JEditorPane bodyPane;
	private static JScrollPane jsp;
	private static JLabel bodyLabel;
	private static JButton save;
	private static JButton load;
	private static JButton cancel;
	private static JButton submit;
	private static File openTemplate;
	private static GridBagConstraints gbc;
	private static JButton insertCNEE;
	private static JButton insertName;
	private static JButton insertDate;
	
	private static JPanel editPanel;
	private static String bodyCont =
			"Dear $CNEE Team,\n"+
			"\n"+
			"Please see attached for today's Titan origin missing data report.\n"+
			"\n"+
			"Please note any data that has already been updated and send back the report.\n"+
			"Thank you.\n\n";
	private static String signature = 
		"Best Regards,\n"+
		"\n"+
		"Joe Tong\n"+
		"\n"+
		"Data Management - LAX\n"+ 
		"2727 Workman Mill Rd.\n"+
		"City of Industry, CA 90601\n"+
		"Tel: 562-908-1688 EXT:235\n"+
		"Tax: 562-908-1699\n"+
		"Email: joe@topocean.com\n"+
		"Website: www.topocean.com";

	public static void giveFocus(){
		dialog.requestFocus();
	}
	public static void open(){
		if(ConfigInfo.LAST_OPEN_TEMPLATE.length()>0){
			openTemplate = new File(FilePath.TEMPLATE_FOLDER_PATH + "\\" + ConfigInfo.LAST_OPEN_TEMPLATE);
			if(openTemplate.exists()){
				parseSavedEmail(openTemplate);
			}else{
				ConfigInfo.LAST_OPEN_TEMPLATE = "";
			}
		}
		bodyPane.setSize(new Dimension(450,500));
		GUIFocusManager.add(dialog);
	}
	public static JEditorPane getBodyPane(){
		return bodyPane;
	}
	public static String getSubject(String csName, String cnee){
		return getMessage(subjectField.getText(),csName, cnee);
	}
	public static String getBody(String csName, String cnee){ //bodyPane.getText()
		return getMessage(bodyCont,csName, cnee) + signature;
	}
	public static void initialize(){
		dialog = new JDialog();
		dialog.setTitle("Edit Mail Template");
		save = new JButton("Save");
		load = new JButton("Load");
		cancel = new JButton("Cancel");
		submit = new JButton("Submit");
		subjectLabel = new JLabel("Subject");
		subjectField = new JTextField();
		bodyLabel = new JLabel("Body");
		bodyPane = new JEditorPane();
		bodyPane.setContentType("text/html");
		jsp = new JScrollPane(bodyPane);
		dialog.setLayout(new GridBagLayout());
		gbc = new GridBagConstraints();
		editPanel = new JPanel();
		
		gbc.insets.top = 4;
		gbc.insets.bottom = 4;
		gbc.insets.left = 4;
		gbc.insets.right =4;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.anchor = GridBagConstraints.LINE_END;
		
		gbc.gridwidth =1;
		gbc.gridx = 0;
		gbc.gridy = 0;
		dialog.add(subjectLabel,gbc);
		gbc.gridx = 1;
		gbc.gridy = 0;
		subjectField.setPreferredSize(new Dimension(400,25));
		dialog.add(subjectField,gbc);
		
		gbc.gridx = 0;
		gbc.gridy = 1;
		dialog.add(bodyLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 0;
		gbc.gridy = 2;
		gbc.gridwidth = 2;
		gbc.gridheight = 3;
		jsp.setPreferredSize(new Dimension(450,500));
		bodyPane.setEditable(true);
		dialog.add(jsp,gbc); 

		buildEditPanel();
		gbc.gridwidth = 1;
		gbc.gridx = 3;
		dialog.add(editPanel,gbc);
		
		gbc.gridheight = 1;
		JPanel buttonPanelTop = new JPanel();
		buttonPanelTop.setBorder(BorderFactory.createTitledBorder("Save / Load Templates"));
		buttonPanelTop.setLayout(new GridBagLayout());
		gbc.gridx = 0;
		gbc.gridy = 0;
		buttonPanelTop.add(save,gbc);
		gbc.gridx = 1;
		gbc.gridy = 0;
		buttonPanelTop.add(load,gbc);
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 5;
		dialog.add(buttonPanelTop,gbc);
		
		gbc.gridwidth = 1;
		JPanel buttonPanelBottom = new JPanel();
		buttonPanelBottom.setLayout(new GridBagLayout());
		gbc.gridx = 0;
		gbc.gridy = 0;
		buttonPanelBottom.add(cancel,gbc);
		gbc.gridx = 1;
		gbc.gridy =0 ;
		buttonPanelBottom.add(submit,gbc);
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 6;
		dialog.add(buttonPanelBottom,gbc);
		
		attachListeners();
		
		GUIFocusManager.setDialogProperties(dialog);
		
		/*
		 * Auto load last used template if available
		 */
		if(ConfigInfo.LAST_OPEN_TEMPLATE.length()>0){
			openTemplate = new File(FilePath.TEMPLATE_FOLDER_PATH + "\\" + ConfigInfo.LAST_OPEN_TEMPLATE);
			if(openTemplate.exists()){
				parseSavedEmail(openTemplate);
			}
		}
	}
	/**
	 * Initializes editing panel
	 */
	private static void buildEditPanel() {
		editPanel = new JPanel();
		editPanel.setLayout(new GridBagLayout());
		insertCNEE = new JButton("Insert CNEE");
		insertCNEE.setFocusable(false);
		insertCNEE.setPreferredSize(new Dimension(120,25));
		insertName = new JButton("Insert Name");
		insertName.setFocusable(false);
		insertName.setPreferredSize(new Dimension(120,25));
		insertDate = new JButton("Insert Date");
		insertDate.setFocusable(false);
		insertDate.setPreferredSize(new Dimension(120,25));
		GridBagConstraints gbc = new GridBagConstraints();
		
		gbc.insets.left = 2;
		gbc.insets.right = 2;
		gbc.insets.top = 2;
		gbc.insets.bottom = 2;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		
		gbc.gridx = 0;
		gbc.gridy = 0;
		editPanel.add(insertCNEE,gbc);
		gbc.gridy = 1;
		editPanel.add(insertName,gbc);
		gbc.gridy = 2;
		editPanel.add(insertDate,gbc);
		
		attachEditListeners((StyledDocument)bodyPane.getDocument());
	}
	/**
	 * Attach listeners to text editing components
	 */
	private static void attachEditListeners(StyledDocument doc){
        
		insertCNEE.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					if(bodyPane.isFocusOwner()){
						bodyPane.getDocument().insertString(MailerGUI.getBodyPane().getCaretPosition(), "$CNEE", null);
					}else if(subjectField.isFocusOwner()){
						StringBuffer b = new StringBuffer(subjectField.getText());
						b.insert(subjectField.getCaretPosition(), "$CNEE");
						subjectField.setText(b.toString());
					}
				} catch (BadLocationException e1) {
					System.out.println("CNEE Insertion failed");
				}
			}
		});
		insertName.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					if(bodyPane.isFocusOwner()){
						bodyPane.getDocument().insertString(MailerGUI.getBodyPane().getCaretPosition(), "$NAME", null);
					}else if(subjectField.isFocusOwner()){
						StringBuffer b = new StringBuffer(subjectField.getText());
						b.insert(subjectField.getCaretPosition(), "$NAME");
						subjectField.setText(b.toString());
					}
				} catch (BadLocationException e1) {
					System.out.println("CNEE Insertion failed");
				}
			}
		});
		insertDate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent f) {
				try{
					Component c = dialog.getFocusOwner();
					if(c == bodyPane){
						bodyPane.getDocument().insertString(MailerGUI.getBodyPane().getCaretPosition(), "$DATE", null);
					}else if(c == subjectField){
						StringBuffer b = new StringBuffer(subjectField.getText());
						b.insert(subjectField.getCaretPosition(), "$DATE");
						subjectField.setText(b.toString());
					}
				} catch (BadLocationException e1) {
					System.out.println("DATE Insertion failed");
				}
			}
		});
	}
	/**
	 * Add listeners to main panel components
	 */
	private static void attachListeners(){
		cancel.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				GUIFocusManager.remove();
			}
		});
		load.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				TemplateSelect.open(openTemplate);
			}
		});
		//save button allows the user to save the current subject and body text in a txt file for
		//future use
		save.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				saveFile();
			}
		});
		submit.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				saveFile();
				GUIFocusManager.remove();
			}
		});
	}
	public static void saveFile(){
		if(openTemplate==null){
			String input = (String)JOptionPane.showInputDialog("Please enter a file name");
			if(input!=null&&input.length()>1){
				try{
					openTemplate = new File(FilePath.TEMPLATE_FOLDER_PATH + input + ".mst");
					openTemplate.createNewFile();
				}catch (Exception e){
					JOptionPane.showMessageDialog(null,"New template creation unsuccessful");
					return;
				}
			}
			else{
				return;
			}
		}
		try {
			ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(openTemplate));
			HTMLDocument doc = (HTMLDocument)bodyPane.getDocument();
			Dictionary<Object,Object> dic = doc.getDocumentProperties();
			dic.put("title", subjectField.getText());
			doc.setDocumentProperties(dic);
			os.writeObject(doc);
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void openNewFile(File file){
		subjectField.setText("");
		bodyPane.setText("");
		openTemplate = file;
	}
	/**
	 * Retrieves data out of a saved email template and populates fields
	 * @param file
	 */
	public static boolean parseSavedEmail(File file){
		if(file!=null){
			if(file.exists()){
				try {					
					try {
						ObjectInputStream os = new ObjectInputStream(new FileInputStream(file));
						Object o = os.readObject();
						HTMLDocument d = (HTMLDocument)o;
						
						bodyPane.setDocument(d);
						
						Object title = d.getProperty("title");
				          //It seems that the extraction of the title property is delayed
				          //Wait until it can be updated
				          int counter = 5;
				          while(title==null){
				        	  if(counter>0){
					        	  try {
									Thread.sleep(100);
						        	title = d.getProperty("title");
						        	if(title!=null)
						        		break;
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
				        		  counter--;
				        	  }else{
				        		  break;
				        	  }
				          }
				          subjectField.setText((String)title);

						  openTemplate = file;
				          return true;
					} catch (ClassNotFoundException e1) {
						JOptionPane.showMessageDialog(null, "Email template corrupted!  File could not be loaded");
						return false;
					}			         
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return false;
	}
	/**
	 * Replaces all key values of a given string with their intended values
	 * @param bodyString string with key values
	 * @param csName String with CS member's name:  empty if not used
	 * @param cnee String with consignee's name: empty if not used
	 */
	public static String getMessage(String text, String csName, String cnee){
		String output = new String(text);
		//To lowercase all words and uppercase the first character
		String[] namelist = csName.toLowerCase().split(" ");
		String editedCSName = "";
		Date dateNow = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("M/d/yyyy");
		for(int i=0;i<namelist.length;i++){
			editedCSName += namelist[i].substring(0, 1).toUpperCase();
			if(namelist[i].length()>1)
				editedCSName += namelist[i].substring(1,namelist[i].length());
			if(i!=namelist.length -1){
				editedCSName+=" ";
			}
		}
		output = output.replaceAll("\\<[^>]*>","");
		output = output.replace("$NAME", editedCSName);
		output = output.replace("$CNEE", cnee);
		output = output.replace("$DATE", sdf.format(dateNow));
		return output;
	}
}
